package com.tangyuan.user.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tangyuan.common.payment.AliPayImpl;
import com.tangyuan.common.payment.WxPayImpl;
import com.tangyuan.common.result.Result;
import com.tangyuan.common.result.ResultCodeEnum;
import com.tangyuan.common.util.CommStatus;
import com.tangyuan.common.util.DateUtil;
import com.tangyuan.model.Orders;
import com.tangyuan.model.UserBalance;
import com.tangyuan.model.activity.*;
import com.tangyuan.result.oConvertUtils;
import com.tangyuan.user.mapper.*;
import com.tangyuan.user.service.*;
import com.tangyuan.vo.RuleDetailsVo;
import com.tangyuan.vo.UserActivityVo;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description: user_activity
 * @Author: jeecg-boot
 * @Date: 2024-03-20
 * @Version: V1.0
 */
@Data
@Service
@Transactional
public class UserActivityServiceImpl extends ServiceImpl<UserActivityMapper, UserActivity> implements IUserActivityService {

    @Autowired
    CommStatus commStatus;
    @Autowired
    private IUserActivityService userActivityService;
    @Autowired
    private IUserHonouredGuestService userHonouredGuestService;
    @Autowired
    private IHonouredGuestService honouredGuestService;
    @Autowired
    private ITicketTypeService ticketTypeService;
    @Autowired
    private ITicketTypeRecordService ticketTypeRecordService;
    @Autowired
    private IEnrollService enrollService;
    @Autowired
    private IEnrollRecordService enrollRecordService;

    @Autowired
    private UserActivityMapper userActivityMapper;
    @Autowired
    private WxPayImpl wxPayService;

    @Autowired
    private UserHonouredGuestMapper userHonouredGuestMapper;

    @Autowired
    private PollRecordMapper pollRecordMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    private IUserBalanceService userBalanceService;

    @Autowired
    private TicketTypeRecordMapper ticketTypeRecordMapper;

    @Autowired
    private EnrollMapper enrollMapper;

    @Transactional
    @Override
    public Result<Object> publishActivity(Long userId, UserActivity userActivity) {
        // 活动时间验证
        if(userActivity.getStartTime().after(userActivity.getEndTime())){
            return Result.build(null, ResultCodeEnum.START_TIME_MORE_THAN_END_TIME);
        }
        userActivity.setUserId(userId);
        userActivity.setIsDeleted(0);
        userActivity.setIsParticipate(1);
        userActivity.setCreateTime(new Date());

        userActivityService.save(userActivity);

                if (userActivity.getHonouredGuestIds()!=null&&!userActivity.getHonouredGuestIds().isEmpty()) {
                    int number = 1;
                    for (Long honouredGuestId : userActivity.getHonouredGuestIds()) {
                        UserHonouredGuest userHonouredGuest = userHonouredGuestService.getById(honouredGuestId);
                        HonouredGuest guest = new HonouredGuest();
                        BeanUtils.copyProperties(userHonouredGuest, guest);
                        guest.setCreateTime(new Date());
                        guest.setUpdateTime(new Date());
                        guest.setActivityId(userActivity.getId());
                        guest.setId(null);
                        guest.setNumberId(number);
                        number++;
                        honouredGuestService.save(guest);
                    }
                }

                if (userActivity.getTicketTypeIds()!=null&&!userActivity.getTicketTypeIds().isEmpty()) {
                    for (Long tickTyTypeId : userActivity.getTicketTypeIds()) {
                        TicketType ticketType = ticketTypeService.getById(tickTyTypeId);
                        TicketTypeRecord ticketTypeRecord = new TicketTypeRecord();
                        BeanUtils.copyProperties(ticketType, ticketTypeRecord);
                        ticketTypeRecord.setCreateTime(new Date());
                        ticketTypeRecord.setUpdateTime(new Date());
                        ticketTypeRecord.setActivityId(userActivity.getId());
                        ticketTypeRecord.setId(null);
                        ticketTypeRecord.setVoteId(tickTyTypeId);
                        ticketTypeRecord.setRemainderNum(ticketType.getVoteNum());
                        if (ticketTypeRecord.getStartTime() == null) {
                            ticketTypeRecord.setStartTime(userActivity.getStartTime());
                            ticketTypeRecord.setVoteTime(userActivity.getEndTime());
                        }
                        ticketTypeRecordService.save(ticketTypeRecord);
                    }
                }

        return Result.ok();
    }

    @Override
    public Result<Object> cancelActivity(Long userId, Long id) {
        
        LambdaUpdateWrapper<UserActivity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(UserActivity::getStatus, 1).eq(UserActivity::getUserId, userId).eq(UserActivity::getId, id);
        userActivityService.update(updateWrapper);
        return Result.ok();
    }

    @Override
    public Result<Object> cancelEnroll(Long userId, Long id) throws IOException {
        
        EnrollRecord enrollRecord = enrollRecordService.getById(id);
        if (enrollRecord == null) {
            return Result.build(null, ResultCodeEnum.ACTIVE_NOT_EXIST);
        }
        if (!Objects.equals(enrollRecord.getUserId(), userId)) {
            return Result.build(null, ResultCodeEnum.YOU_HAVE_NO_RIGHT);
        }
        if (enrollRecord.getIsCancel() != 0) {
            return Result.build(null, ResultCodeEnum.YOU_HAVE_CANCEL);
        }
        Enroll enroll = enrollService.getById(enrollRecord.getEnrollId());
        if (enroll == null) {
            return Result.build(null, ResultCodeEnum.ACTIVE_NOT_EXIST);
        }
        if (enroll.getStatus()==9){
            return Result.build(null, ResultCodeEnum.ACTIVE_HAS_CONFIRM);
        }
        Orders orders = new Orders();
        orders.setPayBalance(enroll.getActivityMoney());
        orders.setRefundBalance(enrollRecord.getVoteMoney());
        orders.setPayType(enroll.getPayType());
        orders.setShopName("活动报名");
        orders.setOrderNo(enroll.getOrderNo());

        if (enroll.getPayType() == 1) {
            wxPayService.refund(orders);
            return Result.ok("微信退款正在处理中,请稍后查询");
        } else if (enroll.getPayType() == 2) {
            Result<Object> refund = AliPayImpl.refund(orders);
            if (refund.isOk()){
                updateEnrollIsCancel(enrollRecord, enroll);
                return Result.ok();
            }else {
                return Result.build(null,ResultCodeEnum.REFUND_FAILED);
            }
        } else if (enroll.getPayType() == 3) {
                balanceRefund(orders, userId);
                updateEnrollIsCancel(enrollRecord, enroll);
                return Result.ok();
        } else if (enroll.getPayType() == 4) {
            // TODO IOS支付退款
        }

        return Result.build(null,ResultCodeEnum.NO_REFUND_METHOD);
    }

    private void updateEnrollIsCancel(EnrollRecord enrollRecord, Enroll enroll) {
        //设置为取消状态
        enrollRecord.setIsCancel(1);
        enrollRecordService.updateById(enrollRecord);

        //退款后添加票中剩余数量
        TicketTypeRecord  ticketTypeRecord=ticketTypeRecordMapper.selectByAId(enroll.getActivityId(), enroll.getVoteId());
        ticketTypeRecord.setRemainderNum(ticketTypeRecord.getRemainderNum()+ enroll.getVoteNum());
        ticketTypeRecordMapper.updateById(ticketTypeRecord);

        //设置已退款状态
        enroll.setStatus(3);
        enrollService.updateById(enroll);
    }

    //余额退款
    private void balanceRefund(Orders orders, Long userId) {
        LambdaQueryWrapper<UserBalance> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserBalance::getUserId, userId);
        queryWrapper.orderByDesc(UserBalance::getCreateTime);
        queryWrapper.last("limit 1");
        UserBalance balance = userBalanceService.getOne(queryWrapper);

        UserBalance userBalance = new UserBalance();
        userBalance.setUserId(userId);
        userBalance.setType(3);
        userBalance.setTransactionId("BM" + oConvertUtils.orderNo());
        userBalance.setOrderNo(orders.getOrderNo());
        userBalance.setUpBalance(orders.getRefundBalance());
        userBalance.setBalance(balance.getBalance().add(orders.getPayBalance()));
        userBalance.setCreateTime(new Date());
        userBalanceService.save(userBalance);

    }

    @Override
    public Result<Object> getActiveById(Long userId, Long id) {
        UserActivity userActivity = userActivityMapper.getActiveById(id);
        return Result.ok(userActivity);
    }

    //确认报名
    @Override
    public Result<Object> completeEnroll(Long userId, Long id) {
        
        EnrollRecord enrollRecord = enrollRecordService.getById(id);
        if (enrollRecord == null) {
            return Result.build(null, ResultCodeEnum.ACTIVE_NOT_EXIST);
        }
        if (!Objects.equals(enrollRecord.getUserId(), userId)) {
            return Result.build(null, ResultCodeEnum.YOU_HAVE_NO_RIGHT);
        }
        if (enrollRecord.getIsCancel()==1){
            return Result.build(null, ResultCodeEnum.YOU_HAVE_CANCEL);
        }
        Enroll enroll = enrollService.getById(enrollRecord.getEnrollId());
        if (enroll == null) {
            return Result.build(null, ResultCodeEnum.ACTIVE_NOT_EXIST);
        }
        if (enroll.getStatus() !=1){
            return Result.build(null, ResultCodeEnum.REGISTRATION_UNPAID);
        }
        if (enroll.getStatus() == 9) {
            return Result.build(null, ResultCodeEnum.ACTIVE_HAS_CONFIRM);
        }
        enroll.setUpdateTime(new Date());
        enroll.setStatus(9);
        enrollService.updateById(enroll);
        enrollRecord.setIsComplete(1);
        enrollRecordService.updateById(enrollRecord);
        //确认成功,添加活动出席人数
        UserActivity userActivity = userActivityMapper.selectById(enroll.getActivityId());
        userActivity.setAttendance(userActivity.getAttendance()+enroll.getVoteNum());
        userActivityMapper.updateById(userActivity);
        return Result.ok();
    }

    @Override
    public Result<Object> getHonouredGuestByVoteNum(Integer pageNum, Integer pageSize, Long userId, UserActivity userActivity) {
        PageHelper.startPage(pageNum, pageSize);
        LambdaQueryWrapper<HonouredGuest> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HonouredGuest::getIsDeleted, 0);
        queryWrapper.eq(HonouredGuest::getActivityId, userActivity.getId());
        queryWrapper.orderByDesc(HonouredGuest::getVoteNum);
        List<HonouredGuest> guestList = honouredGuestService.list(queryWrapper);
        PageInfo<HonouredGuest> honouredGuestPageInfo = new PageInfo<>(guestList);
        return Result.ok(honouredGuestPageInfo);
    }

    @Override
    public Result<Object> getHonouredGuestByNumber(Integer pageNum, Integer pageSize, Long userId, UserActivity userActivity) {

        PageHelper.startPage(pageNum, pageSize);
        LambdaQueryWrapper<HonouredGuest> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HonouredGuest::getIsDeleted, 0);
        // queryWrapper.eq(HonouredGuest::getUserId, user.getId());
        queryWrapper.eq(HonouredGuest::getActivityId, userActivity.getId());
        queryWrapper.like(userActivity.getName() != null && !userActivity.getName().isEmpty(),HonouredGuest::getName, userActivity.getName());
     /*   queryWrapper.and(userActivity.getName() != null && !userActivity.getName().isEmpty(), wrapper -> {
            wrapper.like(userActivity.getName() != null && !userActivity.getName().isEmpty(), HonouredGuest::getName, userActivity.getName());
        });*/
        //
        queryWrapper.orderByAsc(HonouredGuest::getNumberId);
        List<HonouredGuest> guestList = honouredGuestService.list(queryWrapper);
        PageInfo<HonouredGuest> honouredGuestPageInfo = new PageInfo<>(guestList);
        return Result.ok(honouredGuestPageInfo);
    }

    @Override
    public Result<Object> getVoteById(Long voteId) {
        UserActivity userActivity = userActivityMapper.getVoteById(voteId);
        return Result.ok(userActivity);
    }

    @Override
    public Result<Object> editGuest(Long userId, UserHonouredGuest userHonouredGuest) {
        
        userHonouredGuestService.updateById(userHonouredGuest);
        return Result.ok();
    }

    @Override
    public Result<Object> participateActivity(Long userId) {
        //查询用户报名的活动详情
        List<EnrollRecord> enrollRecordlist = enrollRecordService.list(new LambdaQueryWrapper<EnrollRecord>()
                .ne(EnrollRecord::getIsCancel, 1)
                .eq(EnrollRecord::getIsDeleted, 0)
                .eq(EnrollRecord::getUserId, userId));

        if (CollectionUtil.isEmpty(enrollRecordlist)){
            return Result.ok();
        }

        //去重获取活动id
        List<Long> activityIds = enrollRecordlist.stream().map(EnrollRecord::getActivityId).distinct().collect(Collectors.toList());

        //获取活动列表
        List<UserActivity> userActivityList = userActivityMapper.selectList(new LambdaQueryWrapper<UserActivity>()
                .in(UserActivity::getId, activityIds)
                .orderByDesc(UserActivity::getCreateTime));

        //添加活动详情
        for (UserActivity userActivity : userActivityList) {
            userActivity.setEnrollRecords(enrollRecordlist.stream().filter(enrollRecord -> userActivity.getId().equals(enrollRecord.getActivityId())).collect(Collectors.toList()));
        }
        return Result.ok(userActivityList);
    }


    @Override
    public Result<Object> myVote(Long userId) {
        //查询我的投票
        List<PollRecord> pollRecords = pollRecordMapper.selectList(new LambdaQueryWrapper<PollRecord>()
                .eq(PollRecord::getUserId, userId)
                .eq(PollRecord::getIsDeleted, 0));
        if (CollectionUtil.isEmpty(pollRecords)){
            return Result.build(null, ResultCodeEnum.USER_NOT_PARTICIPATE);
        }
        //去重获取活动id
        List<Long> activityIds = pollRecords.stream().map(PollRecord::getActivityId).distinct().collect(Collectors.toList());
        //获取活动列表
        List<UserActivity> userActivityList = userActivityMapper.selectList(new LambdaQueryWrapper<UserActivity>()
                .in(UserActivity::getId, activityIds)
                .orderByDesc(UserActivity::getCreateTime));
        //添加投票详情
        for (UserActivity userActivity : userActivityList) {
            userActivity.setPollRecords(pollRecords.stream().filter(pollRecord -> userActivity.getId().equals(pollRecord.getActivityId())).collect(Collectors.toList()));
        }

        return Result.ok(userActivityList);
    }

    @Override
    public Result<Object> myActivity(Long userId) {
        QueryWrapper<UserActivity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("type", 0);
        queryWrapper.orderByDesc("create_time");
        List<UserActivity> userActivities = userActivityMapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(userActivities)) {
            return Result.build(null, ResultCodeEnum.USER_NOT_PARTICIPATE);
        }
        userActivities.forEach(item -> {
            LambdaQueryWrapper<Enroll> enrollQueryWrapper = new LambdaQueryWrapper<>();
            enrollQueryWrapper.eq(Enroll::getActivityId, item.getId());
            enrollQueryWrapper.and(lambdaQueryWrapper -> lambdaQueryWrapper.eq(Enroll::getStatus, 1).or().eq(Enroll::getStatus, 9));
            enrollQueryWrapper.eq(Enroll::getIsDeleted, 0);
            List<Enroll> enrolls = enrollService.list(enrollQueryWrapper);
            item.setEnrolls(enrolls);
        });
        return Result.ok(userActivities);
    }

    @Override
    public Result<Object> previewWithPoster(Long userId, Long id) {
        UserActivity userActivity = userActivityMapper.selectById(id);
        if (userActivity == null) {
            return Result.build(null, ResultCodeEnum.ACTIVE_NOT_EXIST);
        }
        return Result.ok(userActivity);
    }

    @Override
    public Result<Object> ruleDetails(Long id, RuleDetailsVo ruleDetailsVo) {
        UserActivity userActivity = userActivityService.getById(id);
        BeanUtils.copyProperties(userActivity, ruleDetailsVo);
        return Result.ok(ruleDetailsVo);
    }

    @Override
    public Result checkActiveIsBand(Long userId,Long type) {
        
        List<UserActivityVo> list = userActivityMapper.checkActiveIsBand(userId,type);
        return Result.ok(list);
    }

    @Override
    public Result publishActive(Long userId, Long id) {
        
        Date Nowdate = DateUtil.changeLocalDateTimeToDate(LocalDateTime.now());
        Date date = userActivityMapper.selectEndRTimeById(id);
        if (Nowdate.after(date)) {
            return Result.build(null,ResultCodeEnum.ACTIVE_OVER_TIME);
        }
        Integer examine = userActivityMapper.selectExamineById(id);
        if (examine == 1) {
            userActivityMapper.publishActive(id);
            return Result.ok();
        }
        return Result.build(null, ResultCodeEnum.ACTIVE_NOT_PASS);
    }

    /**
     * 获取用户的活动信息。
     *
     * @param userId 用户ID，用于查询该用户相关的活动信息。
     * @return 返回活动信息的结果对象。如果成功，返回包含活动信息的列表；如果失败，返回错误信息。
     */
    @Override
    public Result<Object> getActivity(Long userId,Integer pageNum,Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        // 验证用户ID的合法性
        if (userId == null) {
            return Result.build(null, ResultCodeEnum.ARGUMENT_VALID_ERROR);
        }
        List<UserActivityVo> userActivities = userActivityMapper.selectListAddName();
        // 检查查询结果是否为空，避免不必要的后续操作
        if (CollectionUtils.isEmpty(userActivities)) {
            return Result.ok(userActivities); // 直接返回空列表
        }
        // 提取活动ID列表
        List<Long> userActivityIds = userActivities.stream().map(UserActivityVo::getId).collect(Collectors.toList());
        //增加阅读数量
        userActivityMapper.setReadNumByIds(userActivityIds);
        // 将Long类型的活动ID转换为Integer类型，以满足后续查询条件
        List<Integer> userActivityIdsInt = userActivityIds.stream().map(s -> Integer.valueOf(String.valueOf(s))).collect(Collectors.toList());

        // 根据活动ID列表和用户ID查询报名情况
        List<Enroll> enrollList=enrollMapper.selectByUserActivityIds(userActivityIdsInt,userId);

        // 标记用户是否参加活动
        for (UserActivityVo userActivity : userActivities) {
            if (userActivity.getType()==1) {
                userActivity.setFee(BigDecimal.valueOf(0));
            }
            // 默认设置为未参加
            userActivity.setIsParticipate(0);
            for (Enroll enroll : enrollList) {
                if (userActivity.getId().equals(enroll.getActivityId())){
                    userActivity.setIsParticipate(1);
                    break; // 找到报名记录后，设置为已参加并跳出循环
                }
            }
        }
        return Result.ok(userActivities);
    }

}
